#include "gtkwindowprivate.h"
#include "gtkaccelgroupprivate.h"
#include "gtkbindings.h"
+#include "gtkcssshadowsvalueprivate.h"
#include "gtkkeyhash.h"
#include "gtkmain.h"
#include "gtkmnemonichash.h"
}
static void
-get_decoration_borders (GtkWidget *widget,
- GtkBorder *window_border,
- GtkBorder *outer_border)
+sum_borders (GtkBorder *one,
+ GtkBorder *two)
{
+ one->top += two->top;
+ one->right += two->right;
+ one->bottom += two->bottom;
+ one->left += two->left;
+}
+
+static void
+get_decoration_size (GtkWidget *widget,
+ GtkBorder *decorations)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
+ GtkBorder border = { 0 };
+ GtkBorder margin;
GtkStyleContext *context;
GtkStateFlags state;
- GdkWindow *window;
- gboolean maximized = FALSE;
- const GtkBorder empty = { 0 };
- GtkBorder outer;
+ GtkCssValue *shadows;
+
+ *decorations = border;
+ if (!priv->client_decorated)
+ return;
+
+ if (gtk_window_get_maximized (GTK_WINDOW (widget)))
+ return;
+
+ state = gtk_widget_get_state_flags (widget);
context = gtk_widget_get_style_context (widget);
- state = gtk_style_context_get_state (context);
- window = gtk_widget_get_window (widget);
- if (window != NULL)
- maximized = gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED;
- if (window_border != NULL)
- {
- if (maximized)
- {
- *window_border = empty;
- }
- else
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-border");
- gtk_style_context_get_border (context, state, window_border);
- gtk_style_context_restore (context);
- }
- }
+ gtk_style_context_save (context);
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND);
+ gtk_style_context_add_class (context, "window-frame");
- if (window_border != NULL || outer_border != NULL)
- {
- if (maximized)
- {
- outer = empty;
- }
- else
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-outer-border");
- gtk_style_context_get_border (context, state, &outer);
- gtk_style_context_restore (context);
- }
+ /* Always sum border + padding */
+ gtk_style_context_get_border (context, state, decorations);
+ gtk_style_context_get_padding (context, state, &border);
+ sum_borders (decorations, &border);
- if (outer_border != NULL)
- {
- *outer_border = outer;
- }
- else
- {
- window_border->left += outer.left;
- window_border->right += outer.right;
- window_border->top += outer.top;
- window_border->bottom += outer.bottom;
- }
- }
+ /* Calculate the size of the drop shadows ... */
+ shadows = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW);
+ _gtk_css_shadows_value_get_extents (shadows, &border);
+
+ /* ... and compare it to the margin size, which we use for resize grips */
+ gtk_style_context_get_margin (context, state, &margin);
+
+ border.top = MAX (border.top, margin.top);
+ border.right = MAX (border.right, margin.right);
+ border.bottom = MAX (border.bottom, margin.bottom);
+ border.left = MAX (border.left, margin.left);
+
+ sum_borders (decorations, &border);
+
+ gtk_style_context_restore (context);
}
static void
-update_border_windows (GtkWindow *window, GtkBorder *border)
+update_border_windows (GtkWindow *window)
{
GtkWidget *widget = (GtkWidget *)window;
GtkWindowPrivate *priv = window->priv;
cairo_region_t *region;
cairo_rectangle_int_t rect;
gint width, height;
+ GtkBorder border;
+ GtkStyleContext *context;
if (priv->border_window[0] == NULL)
return;
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, "window-frame");
+ gtk_style_context_get_margin (context,
+ gtk_widget_get_state_flags (widget),
+ &border);
+ gtk_style_context_restore (context);
+
if (!priv->resizable || gtk_window_get_maximized (window))
{
resize_h = resize_v = FALSE;
"decoration-resize-handle", &handle,
NULL);
- width = gtk_widget_get_allocated_width (widget) - (border->left + border->right);
- height = gtk_widget_get_allocated_height (widget) - (border->top + border->bottom);
+ width = gtk_widget_get_allocated_width (widget) - (border.left + border.right);
+ height = gtk_widget_get_allocated_height (widget) - (border.top + border.bottom);
if (resize_h && resize_v)
{
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_NORTH_WEST],
0, 0,
- border->left + handle, border->top + handle);
+ border.left + handle, border.top + handle);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_NORTH_EAST],
- border->left + width - handle, 0,
- border->right + handle, border->top + handle);
+ border.left + width - handle, 0,
+ border.right + handle, border.top + handle);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH_WEST],
- 0, border->top + height - handle,
- border->left + handle, border->bottom + handle);
+ 0, border.top + height - handle,
+ border.left + handle, border.bottom + handle);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH_EAST],
- border->left + width - handle, border->top + height - handle,
- border->right + handle, border->bottom + handle);
+ border.left + width - handle, border.top + height - handle,
+ border.right + handle, border.bottom + handle);
rect.x = 0;
rect.y = 0;
- rect.width = border->left + handle;
- rect.height = border->top + handle;
+ rect.width = border.left + handle;
+ rect.height = border.top + handle;
region = cairo_region_create_rectangle (&rect);
- rect.x = border->left;
- rect.y = border->top;
+ rect.x = border.left;
+ rect.y = border.top;
rect.width = handle;
rect.height = handle;
cairo_region_subtract_rectangle (region, &rect);
rect.x = 0;
rect.y = 0;
- rect.width = border->right + handle;
- rect.height = border->top + handle;
+ rect.width = border.right + handle;
+ rect.height = border.top + handle;
region = cairo_region_create_rectangle (&rect);
rect.x = 0;
- rect.y = border->top;
+ rect.y = border.top;
rect.width = handle;
rect.height = handle;
cairo_region_subtract_rectangle (region, &rect);
rect.x = 0;
rect.y = 0;
- rect.width = border->left + handle;
- rect.height = border->bottom + handle;
+ rect.width = border.left + handle;
+ rect.height = border.bottom + handle;
region = cairo_region_create_rectangle (&rect);
- rect.x = border->left;
+ rect.x = border.left;
rect.y = 0;
rect.width = handle;
rect.height = handle;
rect.x = 0;
rect.y = 0;
- rect.width = border->right + handle;
- rect.height = border->bottom + handle;
+ rect.width = border.right + handle;
+ rect.height = border.bottom + handle;
region = cairo_region_create_rectangle (&rect);
rect.x = 0;
rect.y = 0;
if (resize_h)
{
- x = border->left + handle;
+ x = border.left + handle;
w = width - 2 * handle;
}
else
{
x = 0;
- w = width + border->left + border->right;
+ w = width + border.left + border.right;
}
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_NORTH],
x, 0,
- w, border->top);
+ w, border.top);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH],
- x, border->top + height,
- w, border->bottom);
+ x, border.top + height,
+ w, border.bottom);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_NORTH]);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_SOUTH]);
if (resize_v)
{
- y = border->top + handle;
+ y = border.top + handle;
h = height - 2 * handle;
}
else
{
y = 0;
- h = height + border->top + border->bottom;
+ h = height + border.top + border.bottom;
}
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_WEST],
0, y,
- border->left, h);
+ border.left, h);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_EAST],
- border->left + width, y,
- border->right, h);
+ border.left + width, y,
+ border.right, h);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_WEST]);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_EAST]);
gtk_widget_set_allocation (widget, allocation);
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
child_allocation.x = 0;
{
update_grip_visibility (window);
set_grip_position (window);
- update_border_windows (window, &window_border);
+ update_border_windows (window);
}
}
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = window->priv;
+ GdkRGBA transparent = { 0.0, 0.0, 0.0, 0.0 };
GdkRectangle rect;
GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget);
set_grip_shape (window);
}
+
+ if (gtk_widget_get_realized (widget))
+ {
+ gdk_window_set_background_rgba (gtk_widget_get_window (widget),
+ &transparent);
+ gtk_widget_queue_resize (widget);
+ }
}
static void
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
- if (!window->priv->has_resize_grip)
+ if (!priv->has_resize_grip)
return FALSE;
- if (priv->client_decorated)
- get_decoration_borders (widget, &window_border, NULL);
-
+ get_decoration_size (widget, &window_border);
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_style_get (widget,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_width (priv->title_box,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_width_for_height (priv->title_box,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_height (priv->title_box,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_height_for_width (priv->title_box,
GtkStyleContext *context;
gboolean ret = FALSE;
GtkAllocation allocation;
- GtkBorder inner_border = { 0 };
- GtkBorder outer_border = { 0 };
+ GtkBorder window_border;
gint title_height;
context = gtk_widget_get_style_context (widget);
+ get_decoration_size (widget, &window_border);
gtk_widget_get_allocation (widget, &allocation);
- if (priv->client_decorated)
- get_decoration_borders (widget, &inner_border, &outer_border);
-
if (!gtk_widget_get_app_paintable (widget) &&
gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
{
{
gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-border");
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND);
+ gtk_style_context_add_class (context, "window-frame");
+
gtk_render_background (context, cr,
- inner_border.left + outer_border.left,
- inner_border.top + outer_border.top,
+ window_border.left, window_border.top,
allocation.width -
- (inner_border.left + inner_border.right +
- outer_border.left + outer_border.right),
+ (window_border.left + window_border.right),
allocation.height -
- (inner_border.top + inner_border.bottom +
- outer_border.top + outer_border.bottom));
+ (window_border.top + window_border.bottom));
gtk_render_frame (context, cr,
- outer_border.left,
- outer_border.top,
- allocation.width - (outer_border.left + outer_border.right),
- allocation.height - (outer_border.top + outer_border.bottom));
- gtk_style_context_remove_class (context, "window-border");
- gtk_style_context_add_class (context, "window-outer-border");
- gtk_render_frame (context, cr,
- 0, 0, allocation.width, allocation.height);
+ window_border.left, window_border.top,
+ allocation.width -
+ (window_border.left + window_border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom));
+
gtk_style_context_restore (context);
}
title_height = gtk_widget_get_allocated_height (priv->title_box);
else
title_height = 0;
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-content");
+
gtk_render_background (context, cr,
- inner_border.left + outer_border.left,
- inner_border.top + outer_border.top +
- title_height,
+ window_border.left,
+ window_border.top + title_height,
allocation.width -
- (inner_border.left + inner_border.right +
- outer_border.left + outer_border.right),
+ (window_border.left + window_border.right),
allocation.height -
- (inner_border.top + inner_border.bottom +
- outer_border.top + outer_border.bottom +
+ (window_border.top + window_border.bottom +
title_height));
- gtk_style_context_restore (context);
+ gtk_render_frame (context, cr,
+ window_border.left,
+ window_border.top + title_height,
+ allocation.width -
+ (window_border.left + window_border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom +
+ title_height));
}
if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)